package com.zmn.oms.zmn.business.impl.work.autoflow.state;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.cube.common.utils.CollectionUtil;
import com.zmn.manager.mq.constant.MqTopicConsts;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.oms.business.interfaces.apply.CancelApplyBService;
import com.zmn.oms.business.interfaces.worktrack.WorkTrackBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderDistributeConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.constant.OrderTagConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.manager.utils.OmsMqTagConsts;
import com.zmn.oms.model.bo.work.apply.cancel.CancelApplyResultBO;
import com.zmn.oms.model.dto.work.modify.must.OrderWorkGrabDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.tag.OrderTag;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.tag.OrderTagService;
import com.zmn.oms.zmn.business.interfaces.grab.NonGridGrabDistributeBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.state.WorkAutoFlowBService;
import com.zmn.oms.zmn.business.interfaces.work.customwork.ZsDistributeWorkBService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * 类描述: 无网格抢单分配
 *
 * @author: HuangChao
 * @since: 2022/07/27 14:08
 */
@Slf4j
@Service("flowNonGridGrabBServiceImpl")
public class FlowNonGridGrabBServiceImpl<T> implements WorkAutoFlowBService<T> {

    @Autowired
    private ZmnMQSender zmnMQSender;
    @Autowired
    private OrderTagService orderTagService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private NonGridGrabDistributeBService nonGridGrabDistributeBService;
    @Autowired
    private ZsDistributeWorkBService zsDistributeWorkBService;
    @Autowired
    private WorkTrackBService workTrackBService;
    @Autowired
    private CancelApplyBService cancelApplyBService;

    @Override
    public ResultDTO<T> condition(OrderWork orderWork) {

        // 只允许新单进抢单池
        if (!Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_NEW)) {
            return ResultDTO.fail("只允许新单进无网格抢单池");
        }

        // 已经是抢单类型不进无网格抢单池
        if (Objects.equals(orderWork.getGrabType(), GlobalConsts.YES)) {
            return ResultDTO.fail("已经是抢单类型不进无网格抢单池");
        }

        // 工程师加单不能自动进抢单池
        if (NumberUtil.isNotNullOrZero(orderWork.getRecommenderId()) && Objects
                .equals(GlobalConsts.OPERATE_USER_TYPE_MASTER, orderWork.getRecommenderType())) {
            return ResultDTO.fail("工程师加单不能自动进无网格抢单池");
        }

        // 结果：已分单 - 进行中，可操作
        List<Integer> supportStatusList = Lists.newArrayList(OrderStatusConsts.WORK_STATUS_ASSIGN);

        // 是否网格化派单
        boolean isGrid = zsDistributeWorkBService.isGridDistribute(orderWork);
        if (!isGrid) {
            return ResultDTO.fail("非平台直派不能自动进无网格抢单池");
        }

        supportStatusList.add(OrderStatusConsts.WORK_STATUS_CONFIRM);

        List<Integer> supportResultStatusList = Lists.newArrayList(OrderStatusConsts.WORK_RESULT_DOING);
        boolean resultStatusSupport = supportResultStatusList.contains(orderWork.getResultStatus());
        boolean statusSupport = supportStatusList.contains(orderWork.getStatus());

        if (!statusSupport) {
            return ResultDTO.fail("不是已确认或已分单状态");
        }

        if (!resultStatusSupport) {
            return ResultDTO.fail("不是进行中状态");
        }

        // 已派单过的，不需要处理
        if (orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_DISTRIBUTE) {
            return ResultDTO.fail("已派单过");
        }

        // 待取消，不允许自动派单
        Integer waitCancelStatus = workTrackBService.getUserWaitCancelStatus(orderWork.getOrderId(), orderWork.getWorkId());
        if (Objects.equals(waitCancelStatus, GlobalConsts.YES)) {
            return ResultDTO.fail("用户申请取消，不可操作");
        }

        CancelApplyResultBO cancelApplyResultBO = cancelApplyBService.getWaitCancelInfo(orderWork.getOrderId(), orderWork.getWorkId());
        if (Objects.equals(cancelApplyResultBO.getUserWaitCancelStatus(), GlobalConsts.YES)) {
            return ResultDTO.fail("用户申请取消，不可操作");
        }

        if (!Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_ASSIGN)) {
            if (!Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_CONFIRM)) {
                return ResultDTO.fail("未确认");
            }
        }

        List<OrderTag> orderTagList = orderTagService.listOrderTagByOrderId(orderWork.getOrderId(), orderWork.getWorkId());
        if (CollectionUtil.isNullOrEmpty(orderTagList)) {
            return ResultDTO.fail("非无网格订单不进无网格抢单池");
        }

        // 高价值用户订单必须手动派单
        boolean highValueUser = orderTagList.stream()
                .anyMatch(tag -> Objects.equals(tag.getTagType(), OrderTagConsts.ORDER_TAG_USER_SYSTEM) &&
                        (Objects.equals(tag.getTagId(), OrderTagConsts.USER_TAG_ID_HIGH_VALUE) || Objects.equals(tag.getTagId(), OrderTagConsts.TAG_ID_HIGH_VALUE_USER)));
        if (highValueUser) {
            return ResultDTO.fail("高价值用户订单必须手动派单");
        }

        // 非无网格订单不允许进普通抢单池
        boolean nonGridGrab = orderTagList.stream().anyMatch(tag -> Objects.equals(tag.getTagId(),
                OrderTagConsts.TAG_ID_NON_GRID));
        if (!nonGridGrab) {
            return ResultDTO.fail("非无网格订单不进无网格抢单池");
        }

        // vVip用户 平台指派
        if (Objects.equals(orderWork.getDistributeWay(), OrderDistributeConsts.DISTRIBUTE_WAY_PLAT)) {
            OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderWork.getOrderId());
            if (Objects.nonNull(orderDetail)) {
                if (Objects.equals(orderDetail.getVvip(), GlobalConsts.YES)) {
                    return ResultDTO.fail("VVIP用户订单必须手动派单");
                }
            }
        }

        // 无网格抢单类型逻辑判断
        OrderWorkGrabDTO orderWorkGrabDTO = new OrderWorkGrabDTO();
        orderWorkGrabDTO.setOrderId(orderWork.getOrderId());
        orderWorkGrabDTO.setWorkId(orderWork.getWorkId());
        orderWorkGrabDTO.setGrabType(GlobalConsts.YES);
        orderWorkGrabDTO.setGrabWay(GlobalConsts.YES);
        orderWorkGrabDTO.setAutoFlow(false);
        orderWorkGrabDTO.setOrderWork(orderWork);
        return ResultDTO.success(orderWorkGrabDTO);
    }

    @Override
    public void execute(T o) {
        try {
            // 无网格抢单
            OrderWorkGrabDTO grabDTO = (OrderWorkGrabDTO) o;
            Boolean flag = nonGridGrabDistributeBService.autoNonGridDistribute(grabDTO);
            if (!flag) {
                // 发送到自动取消队列
                this.sendCancelMessage(grabDTO);
            }
        } catch (Exception e) {
            this.sendCancelMessage((OrderWorkGrabDTO) o);
            log.error("自动分配无网格抢单异常{}", e);
        }
    }

    /**
     * 发送取消消息
     *
     * @param grabDTO
     */
    private void sendCancelMessage(OrderWorkGrabDTO grabDTO) {
        long time = System.currentTimeMillis() + 1000 * 60 * 5;
        String key = String.format("auto-cancel-%s", grabDTO.getOrderId());
        JSONObject jb = new JSONObject();
        jb.put("orderId", grabDTO.getOrderId());
        jb.put("workId", grabDTO.getWorkId());
        log.info("发送延时取消消息：tag:{},key:{},message:{}", OmsMqTagConsts.ORDER_WORK_JXJ_DELAYED_CANCEL_TAG, key, jb.toJSONString());
        zmnMQSender.sendWithStartDeliverTime(MqTopicConsts.ZMN_TOPIC_OMS, OmsMqTagConsts.ORDER_WORK_JXJ_DELAYED_CANCEL_TAG, key, jb.toJSONString(), time);
    }
}
